package com.example.fury.loglistwidget;

/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.util.ArrayList;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;

/**
 * A dummy class that we are going to use internally to store Log data.
 * Generally, this data will be stored in an external and persistent location
 * (ie. File, Database, SharedPreferences) so that the data can persist if the
 * process is ever killed. For simplicity, in this sample the data will only be
 * stored in memory.
 */

/**
 * The AppWidgetProvider for our sample Log widget.
 */
public class LogDataProvider extends ContentProvider {
	public static final Uri CONTENT_URI = Uri
			.parse("content://com.example.fury.loglistwidget.provider");

	public static class Columns {
		public static final String ID = "_id";
		// public static final String LOG = "log";
		public static final String TEXT = "text";
		// public static final String TEMPERATURE = "temperature";
		public static final String LEVEL = "level";
	}

	// private static class State {
	// List<LogEntry> entries = null;
	// boolean play = true;
	// int position = -1;
	// }

	private static final String TAG = LogDataProvider.class.getSimpleName();

	/**
	 * Generally, this data will be stored in an external and persistent
	 * location (ie. File, Database, SharedPreferences) so that the data can
	 * persist if the process is ever killed. For simplicity, in this sample the
	 * data will only be stored in memory.
	 */
	public static final ArrayList<LogEntry> sData = new ArrayList<LogEntry>();
	private static final int WINDOW_SIZE = 100;
	private Level mLastLevel = Level.V;
	private Logcat mLogcat;
	private Prefs mPrefs;
	// private LogDataProvider mThis;
	private boolean mPlay = true;
	private SharedPreferences sharedPreferences;

	private Handler mHandler = new Handler() {
		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.Handler#handleMessage(android.os.Message)
		 */
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case Logcat.CAT_WHAT:
				final String line = (String) msg.obj;

				// Keeping data's size at WINDOW_SIZE
				if (sData.size() >= WINDOW_SIZE) {
					sData.remove(0);
				}

				// cat(line);
				sData.add(new LogEntry(line));
				// sData.add(new LogEntry(line, sData.size()));
				// Log.d(TAG, "CAT_WHAT");

				break;
			case Logcat.CLEAR_WHAT:

				sData.clear();
				Log.d(TAG, "CLEAR_WHAT");
				break;
			}
		}
	};

	@Override
	public boolean onCreate() {
		Log.d(TAG, "onCreate");
		// mThis = this;
		reset();

		return true;
	}

	public void reset() {
		Log.d(TAG, "reset");

		// Context otherAppsContext = null;
		// try {
		// otherAppsContext = createPackageContext(
		// "com.faynasoftlabs.tutorial.android.sharedpreferences", 0);
		// } catch (NameNotFoundException e) {
		// }

		// sharedPreferences = PreferenceManager
		// .getDefaultSharedPreferences(getContext());

		// Toast.makeText(this, R.string.reading_logs,
		// Toast.LENGTH_LONG).show();
		mLastLevel = Level.V;

		if (mLogcat != null) {
			Log.d(TAG, "mLogcat.stop()");
			mLogcat.stop();
		}

		mPlay = true;
		new Thread(new Runnable() {
			public void run() {
				Log.d(TAG, "mLogcat.start()");
				mLogcat = new Logcat(getContext(), mHandler);
				mLogcat.start();
			}
		}).start();
		// Thread.setPriority(Thread.MIN_PRIORITY)
	}

	private void cat(final String s) {
		// if (mLogEntryAdapter.getCount() > WINDOW_SIZE) {
		// mLogEntryAdapter.remove(0);
		// }

		Format format = mPrefs.getFormat();
		Level level = format.getLevel(s);
		if (level == null) {
			level = mLastLevel;
		} else {
			mLastLevel = level;
		}

		final LogEntry entry = new LogEntry(s, level);
		sData.add(entry);

		// if (mPrefs.isAutoScroll() && tailing) {
		// jumpBottom();
		// }
	}

	@Override
	public synchronized Cursor query(Uri uri, String[] projection,
			String selection, String[] selectionArgs, String sortOrder) {
		assert (uri.getPathSegments().isEmpty());
		Log.d(TAG, "query");
		// In this sample, we only query without any parameters, so we can just
		// return a cursor to
		// all the Log data.
		final MatrixCursor c = new MatrixCursor(new String[] { Columns.ID,
				Columns.TEXT
		// , Columns.LEVEL
				});
		int j = sData.size();
		Log.d(TAG, "query" + j);

		for (int i = 0; i < sData.size(); i++) {
			j--;

			final LogEntry data = sData.get(j);
			// final LogDataPoint data = sData.get(i);
			c.addRow(new Object[] { new Integer(i), new String(data.getText())
			// ,data.getLevel()
			});
		}
		// }
		Log.d(TAG, "query|return");
		return c;
	}

	@Override
	public String getType(Uri uri) {
		return "vnd.android.cursor.dir/vnd.loglistwidget.logs";
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// This example code does not support inserting
		return null;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// This example code does not support deleting
		return 0;
	}

	@Override
	public synchronized int update(Uri uri, ContentValues values,
			String selection, String[] selectionArgs) {
		// assert (uri.getPathSegments().size() == 1);
		Log.d(TAG, "update");
		// In this sample, we only update the content provider individually for
		// each row with new
		// temperature values.
		// final int index = Integer.parseInt(uri.getPathSegments().get(0));
		// final MatrixCursor c = new MatrixCursor(new String[] { Columns.ID,
		// Columns.TEXT
		// , Columns.LEVEL
		// });
		// assert (0 <= index && index < sData.size());
		// final LogEntry data = sData.get(index);
		// data.degrees = values.getAsInteger(Columns.TEMPERATURE);
		// data.setText(values.getAsString(Columns.TEXT));
		// Log.d(TAG, data.log);
		// Notify any listeners that the data backing the content provider has
		// changed, and return
		// the number of rows affected.
		Log.d(TAG, "update|notifyChange");
		getContext().getContentResolver().notifyChange(uri, null);
		return 1;
	}

	// private LogDataProvider.State getState() {
	// State state = new State();
	//
	// // state.entries = mLogEntryAdapter.getLogEntries();
	// state.play = mPlay;
	// // int x = mLogList.getScrollX();
	// // int y = mLogList.getScrollY();
	// // state.position = mLogList.pointToPosition(x, y);
	//
	// return state;
	// }
	//
	// private void setState(final LogDataProvider.State state) {
	// if (state != null) {
	// if (!state.play) {
	// // mLogEntryAdapter = new LogEntryAdapter(this, R.layout.entry,
	// // state.entries);
	// // setListAdapter(mLogEntryAdapter);
	// mPlay = false;
	// }
	// // mLogList.post(new Runnable() {
	// // public void run() {
	// // synchronized (LogActivity.this) {
	// // mLogList.setSelection(state.position);
	// // }
	// // }
	// // });
	// }
	// }
}
